package com.kuang.servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

public class FileServlet2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        //判断上传的表单是普通表单还是带文件的表单
        if (!ServletFileUpload.isMultipartContent(request)){
            return;//说明这是一个普通的表单，停止运行
        }

        try {
        //创建上传文件的保存目录，建议在web-inf下，防止用户直接访问到资源
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()){
            uploadFile.mkdir();//文件不存在，创建这个目录
        }


        //创建上传文件的临时目录，建议在web-inf下，防止用户直接访问到资源
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempFile = new File(tempPath);
        if (!tempFile.exists()){
            tempFile.mkdir();//文件不存在，创建这个目录
        }

        //1.创建diskfileitemfactory对象，处理文件或者限制上传大小
        DiskFileItemFactory factory = new DiskFileItemFactory();

        //2.获取servletfileupload
        ServletFileUpload upload = new ServletFileUpload(factory);

        //监听文件上传进度
        upload.setProgressListener(new ProgressListener() {
            @Override
            //pByteRead：已经读取到的文件大小
            //pContextLength 文件总大小
            public void update(long pByteRead, long pContextLength, int items) {
                System.out.println("总大小："+pContextLength+"已上传大小为："+pByteRead);
            }
        });

        //处理乱码问题
        upload.setHeaderEncoding("utf-8");
        //设置单个文件的最大值
        upload.setFileSizeMax(1024*1024*10);
        //设置总共能上传的文件大小
        //1024=1kb  1024*1024=1mb  1mb*10=10mb
        upload.setSizeMax(1024*1024*10);

        //3.处理上传的文件
        //把前端请求解析，。封装为一个fileitem对象,需要从ServletFileUpload获取

            List<FileItem> fileItems = upload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                //fileitem就是每一个表单对象
                //判断上传的文件是普通的表单还是上传文件的表单
                if (fileItem.isFormField()){//这个表单就是一个普通的表单
                    //fieleName指的是前端表单控件的name
                    String fieldName = fileItem.getFieldName();
                    String value = fileItem.getString("UTF-8");
                    System.out.println("这是一个普通的表单"+fieldName+":"+value);
                }else {//这个表单是一个带文件的表单
                    //==================处理文件======================
                    //先获取文件名字
                    String uploadFileName = fileItem.getName();
                    //可能存在文件名不合法的情况
                    if (uploadFileName==null||uploadFileName.trim().equals("")){
                        continue;
                    }
                    //获得上传的文件名字 例如 /images/url/paojie.png
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/" + 1));
                    //获得上传文件的后缀名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf("." + 1));

                    //可以使用UUID 唯一识别的通用码 保证文件名字唯一
                    //uuid.randomuuid 随机生层一个唯一识别的UUID识别码

                    /**
                     * 网络中传输的东西都是需要序列化的
                     * pojo类的东西，如果需要在多个电脑上运行，传输==>需要吧每一个对象都序列化了
                     * jni= java native interface
                     * implements seiralizalble
                     *
                     */
                    String uuidPath = UUID.randomUUID().toString();
                    //==================存放地址======================
                    /**
                     * 存到哪里？  uploadpath
                     * 文件真实存在的路径realpath
                     */
                    String realPath = uploadPath + "/" + uuidPath;
                    //给每个文件创建一个对应的文件夹
                    File realPathFile = new File(realPath);
                    if (!realPathFile.exists()){
                        realPathFile.mkdir();//文件不存在，那就把这个文件创建出来咯
                    }
                    //==================文件传输======================
                    //获得文件上传的流
                    InputStream inputStream = fileItem.getInputStream();

                    //创建一个文件输出流
                    FileOutputStream fos = new FileOutputStream(realPath+"/"+fileName);
                    //创建一个缓冲区
                    byte[] buffer = new byte[1024 * 1024];
                    //判断是否读取完毕
                    int len= 0;
                    //如果大于0则说明还存在数据
                    while ((len=inputStream.read(buffer))>0){
                        fos.write(buffer,0,len);
                    }

                    //关闭流
                    fos.close();
                    inputStream.close();

                    String msg="文件上传成功！";
                    fileItem.delete();//上传成功，清除临时文件
                }
               // return msg;
            }






        } catch (FileUploadException e) {
            e.printStackTrace();
        }


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }
}
